package com.xbd.gateway.config;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.xbd.gateway.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.cloud.CloudClient;
import org.noear.solon.core.LoadBalance;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Gateway;

import java.text.MessageFormat;

@Slf4j
@Component
@Mapping("/**")
public class RouterConfiguration extends Gateway {

    @Override
    protected void register() {
        //添加个前置处理
        before(ctx -> {
            String token = ctx.sessionState().sessionToken();
            System.out.println(token);
        });

        //添加缺省处理
        add(Any.class);
    }

    public static class Any {

        @Mapping
        public String any(Context ctx) throws Throwable {
            //检测请求，并尝试获取二级接口服务名
            String serviceName = ctx.pathMap("/{serviceName}/**").get("serviceName");
            if (serviceName == null) {
                log.error(MessageFormat.format("{0} service not found", serviceName));
                throw new ApiException(500, "服务异常！");
            }

            //转发请求
            String method = ctx.method();
            String server = LoadBalance.get(serviceName).getServer();
            if (server == null) {
                log.error(MessageFormat.format("{0} service not exception", serviceName));
                throw new ApiException(500, "服务异常！");
            }
            HttpRequest request = HttpUtil.createRequest(Method.valueOf(method), server + ctx.path().substring(StrUtil.indexOf(ctx.path(), '/', 2)));
            request.addHeaders(ctx.headerMap());
            request.header(CloudClient.trace().HEADER_TRACE_ID_NAME(), CloudClient.trace().getTraceId());
            request.body(ctx.body());
            HttpResponse response = request.execute();
            if (200 == response.getStatus()) {
                return response.body();
            } else {
                throw new ApiException(response.getStatus(), response.body());
            }

        }
    }

    @Override
    public void render(Object obj, Context context) throws Throwable {
        if (context.getRendered()) {
            return;
        }

        context.setRendered(true);

        Object result;
        if (obj instanceof ApiException) {
            ApiException exception = (ApiException) obj;
            result = exception.data();
        } else {
            //处理java bean数据（为扩展新的）
            result = obj;
        }
        context.result = result;
        //如果想对输出时间点做控制，可以不在这里渲染（由后置处理进行渲染）
        context.render(context.result);
    }
}
